package com.xspace.android.xafcommon.network.exception;

import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;

public class ExHandlerManager implements IExceptionHandler, Runnable
{
    private static ExHandlerManager soleInstance = new ExHandlerManager();

    private boolean bStartThread = false;

    private byte[] exThreadLock;

    private List listExInfo;

    private List listObserver;

    private Thread selfThread = null;

    private ExHandlerManager()
    {
        exThreadLock   = new byte[1];
        listExInfo     = new LinkedList();
        listObserver   = new LinkedList();
    }

    public static ExHandlerManager getInstance()
    {
        return soleInstance;
    }

    private void addExInfo(Exception exception, int id, int cmd)
    {
        ExInfo localExInfo = new ExInfo();
        localExInfo.exception   = exception;
        localExInfo.id  = id;
        localExInfo.code = cmd;

        synchronized (listExInfo)
        {
            listExInfo.add(localExInfo);
        }
    }

    
    private ExInfo getExInfo()
    {
        synchronized (listExInfo)
        {
            int size = listExInfo.size();
            if (size > 0)
            {
                ExInfo localExInfo = (ExInfo) listExInfo.remove(size - 1);
                return localExInfo;
            }
            return null;
        }
    }

    private void noticeHandlers(ExInfo paramExInfo)
    {
        synchronized (listObserver)
        {
            Iterator localIterator = ((List) listObserver).iterator();
            if (localIterator.hasNext())
            {
                IExceptionHandler IExceptionHandler = (IExceptionHandler) localIterator.next();
                IExceptionHandler.onException(paramExInfo.exception, paramExInfo.id, paramExInfo.code);
            }
        }
    }

    public boolean onException(Exception exception, int id,int code)
    {
        addExInfo(exception, id, code);
        synchronized (exThreadLock)
        {
            startRespond();
            return true;
        }
    }

    public void registerObserver(IExceptionHandler paramIExceptionHandler)
    {
        synchronized (listObserver)
        {
            boolean bool = listObserver.contains(paramIExceptionHandler);
            if (!bool)
            {
                listObserver.add(paramIExceptionHandler);
            }
            return;
        }
    }

    public void run()
    {
        if (!bStartThread)
            return;
        ExInfo localExInfo = getExInfo();
        while (true)
        {

            if (!bStartThread || (localExInfo == null))
                break;
            
            if (bStartThread && localExInfo != null)
            {
                noticeHandlers(localExInfo);
            }
            
            synchronized (exThreadLock)
            {
                stopRespond();
                break;
            }
        }
    }

    /**
     * Exit
     */
    public synchronized void exit() {
        System.out.println("Exit thread..");
    }
    
    public void startRespond()
    {
        if(!bStartThread)
        {
            bStartThread = true;
            if(selfThread != null)
            {   
                return ;
            }
            else
            {
                Thread localThread = new Thread(this);
                selfThread = localThread;
                selfThread.start(); 
            }
        }
    }

    public void stopRespond()
    {
        if (bStartThread)
        {
            bStartThread = false;
            Thread.State localState1 = selfThread.getState();
            Thread.State localState2 = Thread.State.TIMED_WAITING;
            if (localState1 == localState2)
            {
                selfThread.interrupt();
            }
            if(null != selfThread)
            {
            }
            selfThread = null;
        }
    }

    public void unregisterObserver(IExceptionHandler iExceptionHandler)
    {
        synchronized (listObserver)
        {
            boolean bool = listObserver.contains(iExceptionHandler);
            if (bool)
            {
                listObserver.remove(iExceptionHandler);
            }
            return;
        }
    }

    class ExInfo
    {
        int code;
        Exception exception;
        int id;

        private ExInfo()
        {
        }
    }
}